package com.ruoyi.business.service.async;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.bizsys.domain.*;
import com.ruoyi.bizsys.mapper.CreditAccountMapper;
import com.ruoyi.bizsys.mapper.CustomerInfoMapper;
import com.ruoyi.bizsys.mapper.SmsSendLogMapper;
import com.ruoyi.bizsys.service.*;
import com.ruoyi.bizsys.utils.BizConstants;
import com.ruoyi.bizsys.vo.CustomerVO;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.RiskConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.riskrule.RuleEngineService;
import com.ruoyi.sms.domain.SmsSendData;
import com.ruoyi.sms.service.ISmsService;
import com.ruoyi.system.service.ISysConfigService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author cyh
 */
@Slf4j
@Component
@AllArgsConstructor
public class AsyncService {

    private RedissonClient redissonClient;


    private RuleEngineService ruleEngineService;

    private ICreditAccountService creditAccountService;


    private ISysConfigService iSysConfigService;

    public static final String AUTOMATIC_RAISE_LOCK = "RaiseLimitLock:";


    ICustomerInfoService customerInfoService;

    CustomerInfoMapper customerInfoMapper;

    CreditAccountMapper creditAccountMapper;

    private ISmsService smsService;

    private IAppUserService appUserService;


    /**
     * 自动提额
     */
    @Async("threadPoolTaskExecutor")
    public void automaticRaiseLimit(String loanSerialNo, String customerNo, RuleIn ruleIn) {
        log.info("客户号{}借据{}开始自动化提额", customerNo, loanSerialNo);
        String lockKey = AUTOMATIC_RAISE_LOCK + customerNo;

        RLock lock = redisCache.lock(lockKey);
        try {
            long start = System.currentTimeMillis();
            //规则引擎
            JSONObject ruleRst = ruleEngineService.riskRuleRaiseLimit(loanSerialNo, customerNo, ruleIn);
            //接收审批结果
            String result = ruleRst.getString(RiskConstants.RULE_RESULT_DEAL_TYPE_KEY);
            //更新信用评级 只在通过/拒绝的时候保存（来自需求）
            if (StringUtils.equalsAny(result, RiskConstants.RULE_RESULT_PASS, RiskConstants.RULE_RESULT_REJECT)) {
                //businessService.upCreditRatingByCustNo(ruleRst.getString(RiskConstants.RULE_CREDIT_RATING), customerNo);
                customerInfoService.upCreditRatingByCustNo(ruleRst.getString(RiskConstants.RULE_CREDIT_RATING), customerNo);
            }
            //不等于Accept 均失败
            if (!StringUtils.equals(result, RiskConstants.RULE_RESULT_PASS)) {
                return;
            }

            //更新授信账户,记录提额日志
            BigDecimal raiseLimit = ruleRst.getBigDecimal(RiskConstants.RULE_RAISE_PASS_ADJUST_LIMIT);
            //校验测算额度 发送短信
            int res = creditAccountService.updateCreditLine(raiseLimit, customerNo, Constants.RaiseLimit.ADJUST_TYPE_AUTOMATIC_ALLOCATION);
            if (res > 0) {
                this.sendRaiseSms(customerNo, raiseLimit);
            }
            log.info("客户号{}提额流程结束", customerNo);
            long end = System.currentTimeMillis();
            log.info("锁占用时间，耗时：" + (end - start) + " ms");
        } catch (Exception e) {
            log.error("自动化提额异常", e);
        } finally {
            lock.unlock();
        }

    }


    private void sendRaiseSms(String customerNo, BigDecimal raiseLimit) {

        log.info("客户{}开始发送提额短信,提额:{}", customerNo, raiseLimit);
        CustomerVO customer = customerInfoMapper.getCustomerInfo(customerNo);
        AppUser appUser = new AppUser();
        appUser.setUserUuid(customer.getUserUuid());
        List<AppUser> appUsers = appUserService.selectAppUserList(appUser);
        JSONObject smsParam = new JSONObject();
        //判断当前用户是否有折扣产品,有则发送短信
        int i = smsService.sendRepaymentPassSms(customer.getCustNo(), appUsers.get(0));
        if(i ==0 ){
            smsParam.put("last_name", customer.getLastName());
            //提额额度
            smsParam.put("limit_adjust", raiseLimit);
            //提额后额度
            CreditAccount account = creditAccountMapper.findInCustNos(customerNo).get(0);
            smsParam.put("credit_line", account.getCreditLine());

            SmsSendData smsData = SmsSendData.builder().noticeType(BizConstants.SMS_NOTICE_TYPE_NOTICE).countryCode(customer.getCountryCode()).phoneNumber(customer.getPhone()).smsParam(smsParam).build();
            //历史用户 || 提额=测算
            if (customer.getPreLine() == null) {
                smsData.setSmsType(BizConstants.SMS_TYPE_RAISE_LIMIT_END_EQUAL_PRE);
            } else {
                int configNum = Integer.parseInt(iSysConfigService.selectConfigByKey("raise_min_num"));
                //小于500不发短信
                if (raiseLimit.compareTo(new BigDecimal(configNum)) < 0) {
                    return;
                }
                int compareResult = raiseLimit.compareTo(customer.getPreLine());
                //提额<测算
                if (compareResult < 0) {
                    smsData.setSmsType(BizConstants.SMS_TYPE_RAISE_LIMIT_END_LESS_PRE);
                }
                //提额=测算
                if (compareResult == 0) {
                    smsData.setSmsType(BizConstants.SMS_TYPE_RAISE_LIMIT_END_EQUAL_PRE);
                }
                //提额>测算
                if (compareResult > 0) {
                    smsData.setSmsType(BizConstants.SMS_TYPE_RAISE_LIMIT_END_GREATER_PRE);
                }
            }
            log.info("客户{}发送提额短信,提额短信内容:{}", customerNo, smsData);
            smsService.sendSms(smsData);
        }
    }
}
